package service

import (
	"encoding/json"
	"fmt"
	"strings"

	mapset "github.com/deckarep/golang-set"
	"github.com/gogs/git-module"
	"github.com/pkg/errors"
	"github.com/redwarn/gotool/httpclient"
	"github.com/sirupsen/logrus"
)

const (
	finiziURL    = "http://kubeapi.devops.finizi.vn/api/v1/deploy/list"
	finmasURL    = "http://kubeapi.devops.finmas.co.id/api/v1/deploy/list"
	cashaloURL   = "http://kubeapi.devops.cashalo.com/api/v1/deploy/list"
	kubeApiToken = "ca16d8238c2cba6958bad192d8c326bf"
)

var repo = git.Repository{Path: "./"}

func GetBranchFromCommitId(tag string) string {
	commitID, err := repo.GetTagCommitID(tag)
	if err != nil {
		logrus.Error("get branch for tag, ", err)
		return ""
	}
	stdout, err := git.NewCommand("branch", "--contains", commitID, "-r").RunInDir(repo.Path)
	if err != nil {
		logrus.Error("get branch for commitId, ", err)
		return ""
	}

	branchNames := strings.Split(strings.ToLower(stdout), "\n")
	branchs := make([]string, len(branchNames))
	for i, branch := range branchNames {
		branchs[i] = strings.TrimSpace(branch)
	}
	return strings.Join(branchs, ";")
}

func IsBranchContainsTag(branchName, tag string) bool {
	if len(branchName) <= 1 {
		return false
	}
	// branchNames := strings.Split(strings.ToLower(branchName), "-")
	branchName = getBranchName(branchName)
	tags := strings.Split(strings.ToLower(tag), "_")
	if tags[1] == "all" {
		return true
	}
	if strings.Contains(branchName, tags[1]) {
		return true
	}
	return false
}

func getBranchName(brancheName string) string {
	branchs := strings.Split(brancheName, ";")
	return branchs[len(branchs)-2]

}
func IsNewTagContainsTag(newTag, Oldtag string) bool {
	commitID, err := repo.GetTagCommitID(newTag)
	if err != nil {
		return false
	}
	stdout, err := git.NewCommand("log", "--format=format:%d", commitID, "-r").RunInDir(repo.Path)
	if err != nil {
		fmt.Println(err)
		return false
	}
	if strings.Contains(stdout, Oldtag) {
		return true
	}
	return false
}

func getCommitsFromTag(tag string) mapset.Set {
	list := mapset.NewSet()
	commitID, err := repo.GetTagCommitID(tag)
	if err != nil {
		return nil
	}
	stdout, err := git.NewCommand("log", "--format=format:%H", commitID, "-r").RunInDir(repo.Path)
	commitIds := strings.Split(stdout, "\n")
	if err != nil {
		return nil
	}
	for _, commitId := range commitIds {
		list.Add(commitId)
	}
	return list
}
func DiffTag(newTag, oldTag string) []string {
	temp := make([]string, 0)
	oldTagCommits := getCommitsFromTag(oldTag)
	if oldTagCommits == nil {
		return []string{"this online tag is not found in gitlab"}
	}
	newTagCommits := getCommitsFromTag(newTag)
	for _, v := range oldTagCommits.Difference(newTagCommits).ToSlice() {
		temp = append(temp, v.(string))
	}
	return temp
}

type KubeResult struct {
	Code int
	Data []struct {
		Name string `json:"name"`
		Tag  string `json:"tag"`
		Unit string `json:"unit"`
	}
}

func getKubeAppVersion(url, token, app string) (string, error) {

	kubeResult := &KubeResult{}
	body := map[string]string{
		"name": app,
	}

	res := httpclient.PostParams(url, token, body)
	if res.StatusCode == 200 {
		err := json.Unmarshal(res.Body, &kubeResult)
		if err != nil {
			return "", errors.New("json unmarshal failure")
		}
		if kubeResult.Code == 200 && len(kubeResult.Data) > 0 {
			return kubeResult.Data[0].Tag, nil
		}
		return "", errors.New("app not found!")
	}
	return "", errors.New("get kubernetes app tag failure!")
}

func GetOnlineVersion(project, tag string) (string, error) {
	var url string
	tags := strings.Split(tag, "_")
	if len(tags) == 4 {
		switch tags[1] {
		case "vn":
			url = finiziURL
		case "id":
			url = finmasURL
		default:
			url = cashaloURL
		}
	}
	return getKubeAppVersion(url, kubeApiToken, project)
}
